import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import defaultSettings from '@/settings'

import { AES, enc, mode, pad } from 'crypto-js'
var CryptoJS = require('crypto-js')

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  withCredentials: false, // 跨域请求时发送 cookies
  timeout: 5000 // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    // do something before request is sent

    if (store.getters.token) {
      // 让每个请求携带token
      config.headers['Authorization'] = getToken()
    }
    const setting = store.getters && store.getters.setting
    const encode = setting.encode && setting.encode.enabled
    if (config.data && encode) {
      const encryptByAES = (message, key) => {
        var keyHex = CryptoJS.enc.Utf8.parse(key)
        var encrypted = CryptoJS.AES.encrypt(message, keyHex, {
          mode: CryptoJS.mode.ECB,
          padding: CryptoJS.pad.Pkcs7
        })
        return encrypted.ciphertext.toString(CryptoJS.enc.Base64).replace(/[\r\n]/g, '')
      }
      config.data = {
        request: encryptByAES(JSON.stringify(config.data), defaultSettings.key)
      }
    }
    return config
  },
  error => {
    // do something with request error
    console.log('A', error) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {
    const res = response.data

    // if the custom code is not 20000, it is judged as an error.
    if (res.code !== 200 && res.code !== 2000) {
      if (res.code === 401) {
        // 请自行在引入 MessageBox
        MessageBox.confirm('你已被下线，可以取消继续留在该页面，或者重新登录', '确定', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload() // 为了重新实例化vue-router对象 避免bug
          })
        })
      } else {
        Message({
          message: res.msg || '网络出错，请稍后重试！',
          type: 'error',
          duration: 5 * 1000
        })
      }
      return Promise.reject(new Error(res.msg || '网络出错，请稍后重试！'))
    } else {
      if (res.code === 2000) {
        const getResultsStr = enc.Hex.parse(res.data)
        const str = enc.Base64.stringify(getResultsStr)
        const decrypted = AES.decrypt(str, enc.Utf8.parse(defaultSettings.key), { iv: enc.Utf8.parse(defaultSettings.iv), mode: mode.CBC, padding: pad.Pkcs7 })

        res.data = JSON.parse(decrypted.toString(enc.Utf8))
      }
      return res
    }
  },
  error => {
    console.log('B', error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service
